package org.footballmanager.pandafootball.system.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.footballmanager.pandafootball.common.annotation.SystemServiceLog;
import org.footballmanager.pandafootball.common.constants.Constants;
import org.footballmanager.pandafootball.common.util.DateUtils;
import org.footballmanager.pandafootball.common.util.MD5Encoder;
import org.footballmanager.pandafootball.system.domain.FootQd;
import org.footballmanager.pandafootball.system.domain.FootUser;
import org.footballmanager.pandafootball.system.domain.enums.QX;
import org.footballmanager.pandafootball.system.form.impl.FootUserSearchForm;
import org.footballmanager.pandafootball.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Random;

@Slf4j
@Service
public class FootUserServiceImpl extends ServiceImpl<FootUser> implements FootUserService {
    @Autowired
    private FootTeamService footTeamService;
    @Autowired
    private FootClubService footClubService;
    @Autowired
    private FootZnxService footZnxService;
    @Autowired
    private FootScinfoService footScinfoService;
    @Autowired
    private FootYysService footYysService;
    @Autowired
    private FootRankService footRankService;
    @Autowired
    private FootLotteryService footLotteryService;
    @Autowired
    private FootUserPersonService footUserPersonService;
    @Autowired
    private FootQdService footQdService;
    @Autowired
    private FootTtService footTtService;
    @Autowired
    private FootZjService footZjService;
    @Autowired
    private FootChipService footChipService;
    @Autowired
    private FootMissionService footMissionService;
    @Autowired
    private FootSociatyInfoService footSociatyInfoService;
    @Autowired
    private EmailSenderService emailSenderService;
    @Autowired
    private FootUserFormationService footUserFormationService;
    @Autowired
    private FootRewardService footRewardService;

    /**
     * 更新用户信息
     *
     * @param entity  实体类
     * @param request 请求
     * @return 成功或失败
     */
    @Override
    @Transactional
    @SystemServiceLog(description = "更新用户信息")
    public int updateNotNull(FootUser entity, HttpServletRequest request) {
        return super.updateNotNull(entity, request);
    }

    /**
     * 删除用户信息
     *
     * @param id      主键
     * @param request 请求
     * @return 是否成功
     */
    @Override
    @Transactional
    public int delete(Serializable id, HttpServletRequest request) {
        FootUser t = this.get(id);
        if (Constants.ADMIN.equals(t.getName())) {
            return 0;
        }
        footYysService.deleteByUserId(t.getId(), request);
        footZnxService.deleteByUserId(t.getId(), request);
        if (t.getJoins()) {
            footChipService.deleteByUserId(t.getId(), request);
            footLotteryService.deleteByUserId(t.getId(), request);
            footMissionService.deleteByUserId(t.getId(), request);
            footScinfoService.deleteByUserId(t.getId(), request);
            footTeamService.deleteByUserId(t.getId(), request);
            footZjService.deleteByUserId(t.getId(), request);
            footClubService.deleteByUserId(t.getId(), request);
            footRankService.deleteByUserId(t.getId(), request);
            footTtService.deleteByUserId(t.getId(), request);
            //删除Sociaty信息
            footSociatyInfoService.deleteByUserid(t.getId(), request);
            //下放该用户的所有球员
            footUserPersonService.deleteAllPerson(t.getId(), request);
            footUserFormationService.deleteByUserId(t.getId(), request);
        }
        log.info("删除用户:" + t.toString());
        return super.delete(id, request);
    }

    /**
     * 获取除管理员的所有用户
     *
     * @param request 请求
     * @return 用户列表
     */
    @Override
    public List<FootUser> getAllWithoutAdmin(HttpServletRequest request) {
        Example example = new Example(FootUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andNotEqualTo("name", Constants.ADMIN);
        if (request != null) {
            FootUser user = (FootUser) request.getSession().getAttribute(Constants.USER);
            criteria.andNotEqualTo("name", user.getName());
        }
        criteria.andEqualTo("delFlag", 0);
        return this.findall(example);
    }

    /**
     * 保存用户信息
     *
     * @param u       用户实体类
     * @param request 请求
     * @return 是否成功
     */
    @Override
    @Transactional
    public int save(FootUser u, HttpServletRequest request) {
        u.setPassword(MD5Encoder.strToMD5(u.getPassword()));
        u.setEnabled(false);
        super.save(u, request);
        footRewardService.saveNewReward(u.getId(), request);
        if (u.getQdId() != null) {
            FootQd qd = footQdService.get(u.getQdId());
            if (qd != null) {
                //添加俱乐部信息
                footClubService.saveNewClub(u, request);
                //添加队伍信息
                footTeamService.saveNewTeam(u, qd, request);
                //添加排位赛信息
                footRankService.saveNewRank(u, qd.getId(), request);
                //添加天梯赛信息
                footTtService.saveNewTt(u, qd.getId(), request);
                //添加战队初始值
                footSociatyInfoService.saveNewSociaty(u, request);
                //添加球队默认阵型
                footUserFormationService.saveNewFormation(u, request);
            }
        }
        return saveNewUser(u, request);
    }

    /**
     * 修改新用户的信息到数据库
     *
     * @param user    用户
     * @param request 请求
     * @return 主键
     */
    @Override
    public int saveNewUser(FootUser user, HttpServletRequest request) {
        user.setSd(false);
        //分别给注册用户和管理员发送收件箱,提醒
        //添加碎片时间信息
        footLotteryService.saveNewLottery(user, request);
        //添加碎片信息
        footChipService.saveNewChip(user, request);
        user.setQx(QX.NORMAL);
        footZnxService.sendZnx(user.getId(), this.getAdminUserid(), "有新注册一般用户", null, null, request);
        //添加热身赛信息
        footYysService.saveNewYys(user, request);
        //随机分配11个球员
        footUserPersonService.randomLow75(user.getId(), request);
        //发送邮件
        emailSenderService.sendRegistEmail(user.getNike(), user.getEmail(), user.getId(), request);
        return super.updateNotNull(user, request);
    }

    /**
     * 获取管理员的用户Id
     *
     * @return 管理员的id
     */
    @Override
    public Long getAdminUserid() {
        Example example = new Example(FootUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("name", Constants.ADMIN);
        criteria.andEqualTo("delFlag", 0);
        FootUser user = this.findByExample(example);
        if (user != null) {
            return user.getId();
        }
        return null;
    }

    /**
     * 三月不登录的删除账号
     */
    @Override
//    @Scheduled(fixedRate = 999999999) //调试用触发方式
    @Scheduled(cron = "0 1 0 * * ?") //每天00点01分触发
    @Transactional
    public void processUserNoLogin() {
        log.info("start Time:" + new Date().toString());
        Date date = new Date();
        List<FootUser> list = this.getAllWithoutAdmin(null);
        if (list == null || list.isEmpty()) {
            return;
        }
        for (FootUser fu : list) {
            if (date.getTime() - fu.getZhdlsj().getTime() > 7776000000L) {
                this.delete(fu.getId(), null);
            }
        }
        log.info("end Time:" + new Date().toString());
    }

    /**
     * 是否让用户登录系统
     *
     * @param issd    是否锁定
     * @param request 请求
     */
    @Override
    @Transactional
    public void cancelLogin(boolean issd, HttpServletRequest request) {
        List<FootUser> userList = this.getAllWithoutAdmin(request);
        if (userList != null && !userList.isEmpty()) {
            for (FootUser user : userList) {
                user.setSd(issd);
                this.updateNotNull(user, request);
            }
        }
    }

    /**
     * 获取会员
     *
     * @return 用户列表
     */
    @Override
    public List<FootUser> findGameIdIsNotNull() {
        Example example = new Example(FootUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIsNotNull("gameId");
        criteria.andNotEqualTo("name", "admin");
        criteria.andEqualTo("delFlag", 0);
        return this.findall(example);
    }

    /**
     * 根据用户名查找用户
     *
     * @param name 姓名
     * @return 用户列表
     */
    @Override
    public FootUser findUserByName(String name) {
        Example example = new Example(FootUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("name", name);
        criteria.andEqualTo("delFlag", 0);
        return this.findByExample(example);
    }

    /**
     * 根据用户昵称查找用户
     *
     * @param nike 昵称
     * @return 用户列表
     */
    @Override
    public List<FootUser> findUsersByNike(String nike) {
        Example example = new Example(FootUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("nike", nike);
        criteria.andEqualTo("delFlag", 0);
        return this.findall(example);
    }

    /**
     * 根据用户名和邮件查找用户
     *
     * @param name  姓名
     * @param email 邮箱
     * @return 用户
     */
    @Override
    public FootUser findUserByNameEmail(String name, String email) {
        Example example = new Example(FootUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("name", name);
        criteria.andEqualTo("email", email);
        criteria.andEqualTo("delFlag", 0);
        return this.findByExample(example);
    }

    /**
     * 根据用户主键，更改用户权限
     *
     * @param userId  用户主键
     * @param qx      权限
     * @param request 请求
     */
    @Override
    @Transactional
    public void changeUser2Vip(Long userId, QX qx, HttpServletRequest request) {
        FootUser user = this.get(userId);
        user.setQx(qx);
        user.setVip(DateUtils.getNextMonthDate(new Date()));
        switch (user.getQx().getValue()) {
            case 3:
                processVip1(user, request);
                break;
            case 4:
                processVip2(user, request);
                break;
            case 5:
                processVip3(user, request);
                break;
            default:
                user.setQx(QX.MEMBER);
                break;
        }
        this.updateNotNull(user, request);
    }

    /**
     * 处理vip1
     *
     * @param user    用户实体类
     * @param request 请求
     */
    private void processVip1(FootUser user, HttpServletRequest request) {
        if (user.getFirst()) {
            footChipService.randomGetChip(user.getId(), 3, 5, request);
            user.setFirst(false);
        }
        footChipService.randomGetChip(user.getId(), 2, 5, request);
        footChipService.randomGetChip(user.getId(), 3, 5, request);
        user.setQx(QX.VIPONE);
    }

    /**
     * 处理vip2
     *
     * @param user    用户实体类
     * @param request 请求
     */
    private void processVip2(FootUser user, HttpServletRequest request) {
        if (user.getFirst()) {
            footChipService.randomGetChip(user.getId(), 3, 5, request);
            footChipService.randomGetChip(user.getId(), 4, 2, request);
            user.setFirst(false);
        }
        footChipService.randomGetChip(user.getId(), 3, 5, request);
        footChipService.randomGetChip(user.getId(), 4, 2, request);
        user.setQx(QX.VIPTWO);
    }

    /**
     * 处理vip3
     *
     * @param user    用户实体类
     * @param request 请求
     */
    private void processVip3(FootUser user, HttpServletRequest request) {
        if (user.getFirst()) {
            footChipService.randomGetChip(user.getId(), 4, 5, request);
            footChipService.randomGetChip(user.getId(), 5, 1, request);
            user.setFirst(false);
        }
        footChipService.randomGetChip(user.getId(), 4, 5, request);
        footChipService.randomGetChip(user.getId(), 5, 1, request);
        user.setQx(QX.VIPTHREE);
    }

    /**
     * 根据用户获取vip的等级加成
     *
     * @param user    用户
     * @param request 请求
     * @return 等级
     */
    @Override
    public double getVipLevel(FootUser user, HttpServletRequest request) {
        double result = 1D;
        Date date = new Date();
        if (null != user && user.getVip() != null) {
            if (user.getVip().getTime() < date.getTime()) {
                user.setQx(QX.MEMBER);
                this.updateNotNull(user, request);
            }
            if (user.getQx().equals(QX.VIPONE)) {
                result = 1.1D;
            } else if (user.getQx().equals(QX.VIPTWO)) {
                result = 1.2D;
            } else if (user.getQx().equals(QX.VIPTHREE)) {
                result = 1.3D;
            }
        }
        return result;
    }

    /**
     * 查询
     *
     * @param entityname         实体类名
     * @param map                参数
     * @param footUserSearchForm 条件
     */
    @Override
    public void search(String entityname, Model map, FootUserSearchForm footUserSearchForm) {
        map.addAttribute(String.format(Constants.FORMNAME, entityname), footUserSearchForm);
        Page<FootUser> page = PageHelper.startPage(footUserSearchForm.getPageIndex(), footUserSearchForm.getPageSize());
        List<FootUser> list = this.findall(footUserSearchForm.buildSearchCommond());
        map.addAttribute(Constants.PI, page.toPageInfo());
        map.addAttribute(String.format(Constants.LISTENTITY, entityname), list);
    }

    /**
     * 删除所有
     *
     * @param footUserSearchForm 条件
     * @param request            请求
     */
    @Override
    public void deleteAll(FootUserSearchForm footUserSearchForm, HttpServletRequest request) {
        if (footUserSearchForm.getSelectIds() != null) {
            String[] result = footUserSearchForm.getSelectIds().split(Constants.COMMA);
            for (String id : result) {
                this.delete(Long.parseLong(id), request);
            }
        }
    }

    /**
     * 邮箱激活用户
     *
     * @param user    用户实体类
     * @param request 请求
     */
    @Override
    public void setEnabledTrue(FootUser user, HttpServletRequest request) {
        user.setEnabled(true);
        this.updateNotNull(user, request);
    }

    /**
     * 更改密码
     *
     * @param user        用户实体类
     * @param request     请求
     * @param map         参数
     * @param isSendEmail 是否发送邮件
     */
    @Override
    public String changePassword(FootUser user, HttpServletRequest request, Model map, boolean isSendEmail) {
        Random random = new Random();
        String newPassword = String.valueOf(random.nextInt(999999));
        user.setPassword(MD5Encoder.strToMD5(newPassword));
        this.updateNotNull(user, request);
        request.getSession().setAttribute("user", user);
        request.getSession().setAttribute(Constants.MSG, "2");
        if (isSendEmail) {
            //发送邮件
            emailSenderService.sendResetPasswordEmail(user.getNike(), user.getEmail(), newPassword, request);
        }
        return newPassword;
    }

    /**
     * 根据邮件查询是否存在
     *
     * @param email 邮箱
     * @return 是否存在
     */
    @Override
    public boolean checkEmail(String email) {
        Example example = new Example(FootUser.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("email", email);
        int result = this.countByCondition(example);
        return result > 0;
    }
}
